package controlador;

import Utilidades.Errores;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import modelo.Modelo;
import modelo.entidades.Entidad;
import vista.Vista;

/**
 *
 * @author jjcamacho
 */
public abstract class AbstractControladorImp<M extends Modelo, V extends Vista, D extends Serializable> implements Controlador<M, V, D> {

    private List<V> vistas = new ArrayList<V>();
    private M modelo;

    @Override
    public void setup(M modelo, List<V> vistas) {
        setModel(modelo);
        modelo.setController(this);
        addViews(vistas);
    }

    @Override
    public void start() {
        for (Vista vista : vistas) {
            vista.display();
        }
    }

    @Override
    public M getModel() {
        return modelo;
    }

    @Override
    public void setModel(M modelo) {
        this.modelo = modelo;
    }

    @Override
    public void nuevaEntidadGesture(List<D> datos) {
        Entidad entidad = generaEntidad(datos);
        try {
            getModel().nuevaEntidad(entidad);
        } catch (SQLException e) {
            Errores.mostrarError(e);
        } catch (Exception e) {
            Errores.mostrarError(e);
        }
    }

    @Override
    public void borraEntidadGesture(D pk) {
        Entidad entidad = generaEntidad(pk);
        try {
            getModel().eliminarEntidad(entidad);
        } catch (SQLException e) {
            Errores.mostrarError(e);
        } catch (Exception e) {
            Errores.mostrarError(e);
        }
    }

    @Override
    public void actualizaEntidadGesture(List<D> datos) {
        Entidad entidad = generaEntidad(datos);
        try {
            getModel().actualizarEntidad(entidad);
        } catch (SQLException e) {
            Errores.mostrarError(e);
        } catch (Exception e) {
            Errores.mostrarError(e);
        }
    }

    @Override
    public void addView(V vista) {
        vista.setModel(modelo);
        vista.setController(this);
        vistas.add(vista);
    }

    private void addViews(List<V> vistas) {
        for (V vista : vistas) {
            addView(vista);
        }
    }

    @Override
    public void removeView(V vista) {
        vistas.remove(vista);
    }

    @Override
    public List<V> getViews(){
        return vistas;
    }

    @Override
    public void fireDataModelChanged() {
        for (Vista vista : vistas) {
            vista.dataModelChanged();
        }
    }

    abstract Entidad generaEntidad(List<D> datos);

    abstract Entidad generaEntidad(D pk);
}
